Este tipo de documento se llama cuaderno de notas o notebook y sirve para mezclar documentación y código al mismo tiempo de manera que los dos estén entrelazados. Elegí crear el primer material aquí de manera que quede estructurado como referencia pero que además puedas jugar con él para practicar lo ahí explicado
A continuación comenzamos con el programa lo primero que hay que hacer para comenzar un programa es llamar a las librerías de trabajo. Las librerías son como una caja con herramientas de trabajo. Diferentes tipos de tareas requieren diferentes tipos de herramientas y la comunidad en consequencia a organizado todas las posibles herramientas en torno a la abstracción de librería. A continuación te hablo sucintamente de las usaremos en esta notebook:
Lo primero que hacemos entonces es importar las dos librerías y además un alias o apodo estandarizado para referirnos a ellas sin escribir tanto. Para ejecutar una celda.
In [1]:
import numpy as np # Alias es np
import matplotlib.pyplot as plt # Alias es plt
Notarás por el número a la izquierda (el número 1) que esa celda es diferente. Ese número significa que es el primero output o salida del programa y sirve para diferenciar e identificar las celdas con código entre sí y de las textuales.
Numpy o np que es su alias tienen la capacidad de crear vectores como fue mencionado anteriormente. Sin más preambulos creo el vector aquí y te explico que viene después:
In [2]:
T_init = 0.0 # Tiempo inicial
Tmax = 10.0 # Tiempo Total
dt= 2.0 # Salto
tiempos = np.arange(T_init, Tmax, dt)
print tiempos
Los nombres son bastante obvios, la primera cantidad T_init
permite iniciar el timepo inicial mientras que Tmax
permite controlar hasta donde llegará el vector de tiempos. Finalmente dt
permite ajustar el tamaño del salto entre un número y el siguiente. La declaración del vector se hace con la instrucción np.arange
(nota que usamos el alias para decir que esta herramientas pertenece a la caja de numpy).
A continuación otro ejemplo para que des una mejor idea de como funcionan los parametros o argumentos de la función:
In [3]:
T_init = 2.0 # Tiempo inicial
Tmax = 8.0 # Tiempo Total
dt= 1.0 # Salto
tiempos = np.arange(T_init, Tmax, dt)
print tiempos
Para modificar una celda de programación como la anterior simplemente dale click y puedes modificar las cosas directamente con tu teclado. Cuando quieras ejectura (o correr) el contenido presiona shift y enter al mismo tiempo (shift + enter). En caso de que no necesites algo más en el menú de la notebook está un menú de ayuda con todos los comandos.
Para asegurarte de que entiendes todo lo que sucede con el vector anterior. Intenta producir un vector que vaya del 10 al 15 con saltos de 0.2. Lo que debeŕia de aparecer una vez que ejecutes la celda es algo como:
(10, 10.2, 10.4 ... y así sucesivamente hasta el 15 o el número más cercano).
Ahora que tenemos un vector de tiempo, es decir un conjunto de valores con los tiempos y podemos manipular nos gustaría saber como se modifica una señal en esos tiempos. La señal que usaremos será el seno que está incluido en la librería de numpy. Primero definamos de nuevo el vector de tiempos y luego directamente evaluaremos el seno en esos
In [4]:
%matplotlib inline
# Esto es para que las gráficas se muestren en patanlla en lugar de una ventana aparte.
T_init = 0.0 # Tiempo inicial
Tmax = 20.0 # Tiempo Total
dt= 1.0 # Salto
tiempos = np.arange(T_init, Tmax, dt)
# El siguiente comando es equivalente a calcular el seno en TODOS los tiempos de arriba.
onda = np.sin(tiempos) # La onda evaluada en todos los tiempos. sin=seno=sinus
plt.plot(tiempos, onda) # Muestra en pantalla
Out[4]:
Notarás que la onda se ve bastante mal deformada, si buscas en google una fotografía del seno deberías encontrar que en realidad se debería de ver algo como así:
Para entender por que se produce esta deformación hay que recordar que en realidad estamos trabajando con puntos. Cada uno de los elementos de nuestro vector tiempos
es en realidad un punto. Por otro lado cuando graficamos de esta manera la librearía automaticamente construye lineas entre los puntos, para evitar que la librearía haga eso necesitamos ser explicitos con ella de la siguiente manera:
In [14]:
onda = np.sin(tiempos) # La onda evaluada en todos los tiempos. sin=seno=sinus
plt.plot(tiempos, onda, '*-') # El astericos indica que queremos los puntos, el guion que los queremos encadenados
Out[14]:
Basandonos en esta imagen debería ser notorio que el problema principal es que no tenemos suficientes puntos para cubrir la señal de manera adecuada. Este tipo de observaciones dan pie al tipo de invetigaciones de cuantos puntos concretos son necesarios para recuperar la información de una señal (teoría de la información) y más particularmente el fenomeno de aliasing en el procesamiento de señales. Pero esto es para una futura discusión y simplemente un comentario lateral.
Volviendo al problema que tenemos a la mano la solución es hacer más pequeños los satlos entre los números para tener más
In [6]:
T_init = 0.0 # Tiempo inicial
Tmax = 20.0 # Tiempo Total
dt= 0.1 # Salto ESTOS SON MÁS PEQUEÑOS AHORA
tiempos = np.arange(T_init, Tmax, dt)
# El siguiente comando es equivalente a calcular el seno en TODOS los tiempos de arriba.
onda = np.sin(tiempos) # La onda evaluada en todos los tiempos. sin=seno=sinus
plt.plot(tiempos, onda, '*-') # Muestra en pantalla
Out[6]:
Como ejercicio deberías de modificar los valores de dt
y los tiempos iniciales y finales para ver como eso afecta la gráfica. Otra cosa que puedes hacer es leer en google sobre los commandos xlim and ylim y agregarlos al pequeño programa de arriba para ver como afectan la visualización.
Finalmente para comenzar a trabajar con distintas frecuencias será necesario ajustar las unidades apropiadas, esto lo discutiremos en persona.
Supongamos que queremos una onda cuyo frequencia sea 1.0. Es decir un ciclo por unidad, la manera matemática de hacer esto es multiplicar los tiempos por la frequencia adecuada. En el siguiente código nota como los tiempos son multiplicados por la frequencia f además de esto también multiplicamos por la longitud del circulo para finalmente tener las unidades adecuadas. Más de esto en nuestra discusión en persona.
In [9]:
T_init = 0.0
Tmax = 20.0
dt= 0.1
tiempos = np.arange(T_init, Tmax, dt)
f = 1.0 # Frequencia
unidades = 2 * np.pi # Esta es la longitud del circulo
onda = np.sin(f * unidades * tiempos) # La onda evaluada en todos los tiempos. sin=seno=sinus
plt.plot(tiempos, onda, '*-') # Muestra en pantalla
Out[9]:
Notarás que la frecuencia es demasiado alta y que por lo tanto no se puede apreciar correctamente, modifiquemos los tiempos finales para ver esto desde otro angulo
In [10]:
T_init = 0.0
Tmax = 5.0
dt= 0.1
tiempos = np.arange(T_init, Tmax, dt)
f = 1.0 # Frequencia en Hz
unidades = 2 * np.pi # Esta es la longitud del circulo
onda = np.sin(f * unidades * tiempos) # La onda evaluada en todos los tiempos. sin=seno=sinus
plt.plot(tiempos, onda, '*-') # Muestra en pantalla
Out[10]:
Nota como hemos movido el tiempo final a 5. La tarea final será que modifiques el código de que manera que se pueda gráficar y visualizar correctamente una ondea de 440 Hz. Esto involucrará modificar la frequencia, también las unidades de timepo apropiadas y los limites de lo que vamos a gráficar.
In [ ]: